package cn.nawang.ebeim.client.service;

import cn.nawang.ebeim.client.constants.Constant;
import cn.nawang.ebeim.client.dto.ClientDto;
import cn.nawang.ebeim.client.process.PersistentObject;
import cn.nawang.ebeim.client.process.Process;
import cn.nawang.ebeim.client.process.ProcessType;
import cn.nawang.ebeim.client.task.DataSourceTimerTask;
import cn.nawang.ebeim.client.transfer.TransferObject;
import cn.nawang.ebeim.client.version.*;
import cn.nawang.ebeim.persist.dao.DataSourceDao;
import cn.nawang.ebeim.persist.dao.DataSourceDaoImpl;
import cn.nawang.ebeim.persist.domain.DataSource;
import com.alibaba.fastjson.JSON;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;

import static cn.nawang.ebeim.client.constants.Constant.WORKING_DIR;

/**
 * Created by GanJc on 2016/1/20.
 */
public class ClientService {

    private static final Logger LOG = LoggerFactory.getLogger(ClientService.class);

    private Random random = new Random();

    private ClientDto dto ;

    DataSourceDao dataSourceDao = new DataSourceDaoImpl();

    public ClientService(ClientDto dto) {
        this.dto = dto;
        init(dto);
    }

    //初始化工作
    private void init(ClientDto dto) {
//        new DataSourceTimerTask(dto).start();
        //加载工作目录
        File workingDir = new File(Constant.WORKING_DIR);
        if(!workingDir.exists()){
            LOG.info("工作目录不存在,创建工作目录:{}",workingDir);
            workingDir.mkdirs();
        }else {
            LOG.info("工作目录存在,搜索工作目录:{}",workingDir);
            //加载.swap文件 生成未完成任务
            for (File file : workingDir.listFiles()) {
                if(file.getName().endsWith(".swap")){
                    FileInputStream input = null;
                    try {
                        input = new FileInputStream(file);
                        List<String> strings = IOUtils.readLines(input);
                        PersistentObject obj = JSON.parseObject(strings.get(0), PersistentObject.class);
                        LOG.info("临时文件:{}",obj);
                        LinkedList<TransferObject> objects = new LinkedList<TransferObject>(obj.getObjects());
                        Process process = new Process(obj.getName(),obj.getType(),objects,obj.getTotalFileNum(),obj.getSuccessFileNum(),obj.getRate());
                        if(ProcessType.DOWNLOAD == obj.getType()){
                            dto.addDownloadProcess(process);
                        }else if(ProcessType.UPLOAD == obj.getType()){
                            dto.addUploadProcess(process);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }finally {
                        IOUtils.closeQuietly(input);
                    }
                }
            }
        }
    }


    public void addDownloadProcess(String dsId, Integer version, Long id) {
        VersionTree versionTree = this.getVersionTree(dsId,version);
        VersionTreeInfo versionTreeInfo = versionTree.versionTreeInfo();

        List<FileNode> fileNodes = new ArrayList<>();

        List<DirectoryNode> dirNodes = versionTreeInfo.getDirNodes();
        for (DirectoryNode dirNode : dirNodes) {
            if(dirNode.getId() == id){
                versionTreeInfo = dirNode.versionTreeInfo(new VersionTreeInfo());
                fileNodes = versionTreeInfo.getFileNodes();
                break;
            }
        }

        if(fileNodes.size()==0){
            for (FileNode fileNode : versionTreeInfo.getFileNodes()) {
                if(fileNode.getId() == id){
                    fileNodes.add(fileNode);
                    break;
                }
            }
        }

        dto.addDownloadProcess(new Process(id.toString(),ProcessType.DOWNLOAD,fileNodes));
    }

    public void addUploadProcess(String dsId,String root) {
        //新增数据源 生成版本树
        VersionTree versionTree = null ;
        versionTree = new VersionTree(dsId);
        versionTree.generateVersionTree(root);
        versionTree.saveVersionTree(WORKING_DIR + File.separator + dsId + File.separator + "version"); //保存路径、保存版本号
        VersionTreeInfo versionTreeInfo = versionTree.versionTreeInfo();

        //在数据库中插一条数据

        dataSourceDao.saveDataSource(new DataSource(dsId,root,
                new File(root).getName(),
                versionTreeInfo.getDirCount(),
                versionTreeInfo.getFileCount()
        ));
        List<FileNode> fileNodes = versionTree.versionTreeInfo().getFileNodes();
        dto.addUploadProcess(new Process(dsId, ProcessType.UPLOAD,fileNodes));
    }

    public List<DataSource> getDataSourceList() {
        return dataSourceDao.findDataSources();
    }


    public void removeUploadProcess(String dsId) {
        Process process = dto.uploadProcesses.get(dsId);
        if(process!=null){
            process.stop();
            dto.uploadProcesses.remove(dsId);
        }
    }

    public void removeDownloadProcess(String dsId) {
        Process process = dto.downloadProcesses.get(dsId);
        if(process!=null){
            process.stop();
            dto.downloadProcesses.remove(dsId);
        }
    }

    public void startUploadProcess(String dsId) {
        Process process = dto.uploadProcesses.get(dsId);
        if(process!=null){
            process.start();
        }
    }

    public void pauseUploadProcess(String dsId) {
        Process process = dto.uploadProcesses.get(dsId);
        if(process!=null){
            process.pause();
        }
    }

    public void startDownloadProcess(String dsId) {
        Process process = dto.downloadProcesses.get(dsId);
        if(process!=null){
            process.start();
        }
    }

    public void pauseDownloadProcess(String dsId) {
        Process process = dto.downloadProcesses.get(dsId);
        if(process!=null){
            process.pause();
        }
    }

    public VersionTree getVersionTree(String dsId,int version) {
        VersionTree versionTree = VersionTree.valueOf(
                WORKING_DIR + File.separator +dsId + File.separator +"version" +File.separator + version);
        return versionTree;
    }
}
